<template>
  <view class="canvas-container" :style="`height: ${this.height}px;width:${this.width}px`">
    <canvas :canvas-id="`${this.id}-circle-line-chart__axis`" :style="`height: ${this.height}px;width:${this.width}px`"></canvas>
  </view>
</template>

<script>
import {createCanvasContext} from "@tarojs/taro"
import maxBy from "lodash.maxby";
import minBy from "lodash.minby";

/**
 *  config:{
 *    yAxis:{
 *      base:number,
 *      top:number,
 *      display:[{value:number,label:string}],
 *      unit:number // 假设为 10,意味着每 10 为一个单位,Y 轴就是 10,20,30
 *    }
 *    dataList:[{}]
 *  }
 *  1. 根据dataList,决定 x 轴如何渲染: 数组有多少个元素, x 轴就有多少个标记
 *  2. 根据yAxis.base,决定 Y 轴的底线在哪里,低于底线的一概按底线显示
 *  3. 根据yAxis.top,决定 Y 轴的最高线在哪里,低于底线的一概按最高显示
 *  4. 将 dataList 中的数据进行整理: 低于 base 的设置为 base,高于 top 的设置为 top
 *  5. 将 yAxis.display 进行遍历,把 value 和 label 画在相应位置
 */

export default {
  name: "line-chart",
  props: {
    id:{
      type:String,
      required:true,
    },
    width: {
      type: Number,
      default: 300,
    },
    height: {
      type: Number,
      default: 210,
    },
    lineColor:{
      type:String,
      default:"#6C63FF",
    },
    config: {
      type: Object,
      default: () => {
        return {
          yAxis: {
            unit: 1,
            base: 6,// y 轴最小值
            top: 7,// y 轴最大值
            display: [
              // 必须按顺序
              {value: 6, label: "6h"},
              {value: 7, label: "7h"},
              {value: 8, label: "8h"},
            ],
          },
          // x 轴上有多少个点
          dataset: [
            {value: 8},
            {value: 3},
            {value: 6},
            {value: 6},
            {value: 2},
            {value: 2},
            {value: 5},
            {value: 7},
            {value: 1},
            {value: 8},
          ],
        };
      }
    },
    paddingTop: {
      type: Number,
      default: 18,
    },
    paddingBottom: {
      type: Number,
      default: 40,
    },
    leftMargin: {
      type: Number,
      default: 30,
    }
  },
  data() {
    return {
      axisCanvas: null, //画布实例
    }
  },
  methods: {
    drawAxis() {
      this.drawX();
      this.drawY();
    },
    // 画 X 轴刻度部分
    drawX() {
      const paddingTop = 20;
      const paddingButton = 40;
      const leftMargin = 30;
      const justifyYAxis = 10;
      let everyTextSpace = (this.width - leftMargin) / this.config.dataset.length; // X 轴多少距离画一个点
      // dataset 里面的每条数据,对应着一个 x 轴上的点
      this.config.dataset.forEach((data, index) => {
        const isBold = index % 5 === 0 && index != 0; // 5 的倍数就加粗
        this.axisCanvas.setFillStyle("#999");
        this.axisCanvas.arc(index * everyTextSpace + leftMargin, this.height - paddingButton + justifyYAxis, isBold ? 2 : 1, 0, 10);
        this.axisCanvas.fill();
        this.axisCanvas.draw(true);
      })
    },
    // 画 Y 轴刻度部分
    drawY() {
      this.drawLabelOfYAxis()
    },
    // Y 轴的刻度
    drawLabelOfYAxis() {
      this.config.yAxis.display.forEach((item, index) => {
        const everySpaceInYAxis = this.height / this.config.yAxis.display.length;
        let yPosition = this.height - everySpaceInYAxis * index - (this.paddingTop + this.paddingBottom);
        this.axisCanvas.fillText(item.label, 0, yPosition);
        this.axisCanvas.draw(true);
        this.axisCanvas.moveTo(0 + 24, yPosition - 3);// 在左边留点空隙
        this.axisCanvas.lineTo(this.width - 12, yPosition - 3);// 根据文字大小向上调整
        this.axisCanvas.setLineWidth(0.5);
        this.axisCanvas.setStrokeStyle("#ccc");
        this.axisCanvas.stroke();
        this.axisCanvas.draw(true);
      });
    },

    // 画线
    drawBezier() {
      // 拿到某个点的数据以后,根据这个点的数据算出来这个点需要在 Y 轴的什么位置
      const getYPosition = (value)=>{
        const bottomY = this.height-this.paddingBottom;//Y 轴最低点
        // 如果超过了 Y 轴可接受的最大值,就直接显示在顶点
        if(value>=maxYValue){
          return 0;
        }
        // 如果小于 Y 轴可接受的最小值,直接显示在底部,paddingBottom 空间需要预留,是因为底部还有刻度表
        if(value<=minYValue){
          return this.height - this.paddingBottom;
        }
        return this.height * (((maxYValue - value) / (maxYValue - minYValue)))-this.paddingBottom-12;
      }
      const max = maxBy(this.config.dataset, "value").value;
      const min = minBy(this.config.dataset, "value").value;
      const maxYValue = maxBy(this.config.yAxis.display, "value").value; // Y 轴能接受的最大值
      const minYValue = minBy(this.config.yAxis.display, "value").value;
      let everyXSpace = (this.width - this.leftMargin) / this.config.dataset.length; // X 轴多少距离画一个点
      this.axisCanvas.moveTo(this.leftMargin, getYPosition(this.config.dataset[0].value));
      this.config.dataset.forEach((item, index) => {
        this.axisCanvas.lineTo(
          everyXSpace*(index)+this.leftMargin,
          getYPosition(item.value),
        );
      });
      this.axisCanvas.setStrokeStyle(this.lineColor);
      this.axisCanvas.setLineWidth(5);
      this.axisCanvas.setLineCap("round");
      this.axisCanvas.setLineJoin("round");
      this.axisCanvas.stroke();
      this.axisCanvas.draw(true);
    }
  },
  created() {
    this.axisCanvas = createCanvasContext(`${this.id}-circle-line-chart__axis`);
    this.drawAxis();
    this.drawBezier();
  }
}
</script>

<style scoped>

</style>
